package com.ibeeking.found.cop.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.cop.b.rest.service.IFriendsFollowService;
import com.ibeeking.found.cop.service.common.dos.CopEmployeeDO;
import com.ibeeking.found.cop.service.common.dos.FriendsFollowDO;
import com.ibeeking.found.cop.service.common.enums.WxCpFriendSoruceEnum;
import com.ibeeking.found.cop.service.common.param.FriendsFollowParam;
import com.ibeeking.found.cop.service.common.query.FriendsFollowPageQuery;
import com.ibeeking.found.cop.service.common.query.FriendsFollowQuery;
import com.ibeeking.found.cop.service.common.vo.FriendsFollowVO;
import com.ibeeking.found.cop.service.mapper.CopEmployeeMapper;
import com.ibeeking.found.cop.service.mapper.FriendsFollowMapper;
import com.ibeeking.found.id.GenerateId;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.date.DateUtil;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName FriendsFollowServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class FriendsFollowServiceImpl extends ServiceImpl<FriendsFollowMapper, FriendsFollowDO> implements IFriendsFollowService {

    @Resource
    private FriendsFollowMapper friendsFollowMapper;

    @Resource
    private CopEmployeeMapper copEmployeeMapper;

    @Override
    public List<FriendsFollowVO> list(FriendsFollowQuery query) {
        List<FriendsFollowDO> entityDOS = friendsFollowMapper.selectList(new LambdaQueryWrapper<FriendsFollowDO>()
                .eq(query.getId() != null, FriendsFollowDO::getId, query.getId())
                .eq(query.getFriendsId() != null, FriendsFollowDO::getFriendsId, query.getFriendsId())
                .eq(StringUtils.isNotBlank(query.getFriendsCode()), FriendsFollowDO::getFriendsCode, query.getFriendsCode())
                .like(StringUtils.isNotBlank(query.getFriendsName()), FriendsFollowDO::getFriendsName, query.getFriendsName())
                .eq(query.getEmployeeId() != null, FriendsFollowDO::getEmployeeId, query.getEmployeeId())
                .eq(StringUtils.isNotBlank(query.getEmployeeCode()), FriendsFollowDO::getEmployeeCode, query.getEmployeeCode())
                .eq(query.getSourceFrom() != null, FriendsFollowDO::getSourceFrom, query.getSourceFrom())
                .orderByDesc(FriendsFollowDO::getBuildTime)
        );
        List<FriendsFollowVO> entityVOS =JsonUtils.jsonToList(entityDOS, FriendsFollowVO.class);
        if(Collections3.isNotEmpty(entityVOS)) {
            List<CopEmployeeDO> copEmployeeDOList = copEmployeeMapper.selectList(new LambdaQueryWrapper<CopEmployeeDO>());
            Map<Long, String> copEmployeeNameMaps = Collections3.isNotEmpty(copEmployeeDOList)?copEmployeeDOList.stream().collect(Collectors.toMap(CopEmployeeDO::getId, CopEmployeeDO::getEmployeeName, (o, n) -> n)):null;

            entityVOS.forEach(x -> {
                x.setSourceFromDesc(WxCpFriendSoruceEnum.getDescByCode(x.getSourceFrom()));
                if(copEmployeeNameMaps!=null && copEmployeeNameMaps.containsKey(x.getEmployeeId())){
                    x.setEmployeeName(copEmployeeNameMaps.get(x.getEmployeeId()));
                }
            });
        }
        return entityVOS;
    }

    @Override
    public Page<FriendsFollowVO> pageList(FriendsFollowPageQuery pageQuery) {
        LambdaQueryWrapper<FriendsFollowDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(pageQuery.getId() != null, FriendsFollowDO::getId, pageQuery.getId())
                .eq(pageQuery.getFriendsId() != null, FriendsFollowDO::getFriendsId, pageQuery.getFriendsId())
                .eq(StringUtils.isNotBlank(pageQuery.getFriendsCode()), FriendsFollowDO::getFriendsCode, pageQuery.getFriendsCode())
                .like(StringUtils.isNotBlank(pageQuery.getFriendsName()), FriendsFollowDO::getFriendsName, pageQuery.getFriendsName())
                .eq(pageQuery.getEmployeeId() != null, FriendsFollowDO::getEmployeeId, pageQuery.getEmployeeId())
                .eq(StringUtils.isNotBlank(pageQuery.getEmployeeCode()), FriendsFollowDO::getEmployeeCode, pageQuery.getEmployeeCode())
                .eq(pageQuery.getSourceFrom() != null, FriendsFollowDO::getSourceFrom, pageQuery.getSourceFrom())
                .orderByDesc(FriendsFollowDO::getBuildTime);
        Page<FriendsFollowDO> entityDOPages = friendsFollowMapper.selectPage(new Page<FriendsFollowDO>(pageQuery.getPageNum(), pageQuery.getPageSize()), wrapper);
        Page<FriendsFollowVO> entityVOPages = BeanUtil.convertPage(entityDOPages, FriendsFollowVO.class);

        if(entityVOPages!=null && entityVOPages.getSize()>0) {
            List<CopEmployeeDO> copEmployeeDOList = copEmployeeMapper.selectList(new LambdaQueryWrapper<CopEmployeeDO>());
            Map<Long, String> copEmployeeNameMaps = Collections3.isNotEmpty(copEmployeeDOList)?copEmployeeDOList.stream().collect(Collectors.toMap(CopEmployeeDO::getId, CopEmployeeDO::getEmployeeName, (o, n) -> n)):null;

            entityVOPages.getRecords().forEach(f -> {
                f.setSourceFromDesc(WxCpFriendSoruceEnum.getDescByCode(f.getSourceFrom()));
                if(copEmployeeNameMaps!=null && copEmployeeNameMaps.containsKey(f.getEmployeeId())){
                    f.setEmployeeName(copEmployeeNameMaps.get(f.getEmployeeId()));
                }
            });
        }
        return entityVOPages;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(FriendsFollowParam param) {
        FriendsFollowDO entityDO = BeanUtil.convertBean(param, FriendsFollowDO.class);
        entityDO.setId(GenerateId.generateId());
        entityDO.setCreateBy(UserUtils.getUserId());
        entityDO.setCreateTime(LocalDateTime.now());
        entityDO.setModifyTime(LocalDateTime.now());
        return friendsFollowMapper.insert(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean modify(FriendsFollowParam param) {
        FriendsFollowDO entityDO = BeanUtil.convertBean(param, FriendsFollowDO.class);
        entityDO.setModifyBy(UserUtils.getUserId());
        entityDO.setModifyTime(LocalDateTime.now());
        return friendsFollowMapper.updateById(entityDO) > 0;
    }

    @Override
    public FriendsFollowVO view(Long id) {
        FriendsFollowDO entityDO = friendsFollowMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        FriendsFollowVO entityVO = BeanUtil.convertBean(entityDO, FriendsFollowVO.class);
        if(entityVO != null) {
            entityVO.setSourceFromDesc(WxCpFriendSoruceEnum.getDescByCode(entityVO.getSourceFrom()));
        }
        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean del(Long id) {
        FriendsFollowDO entityDO = friendsFollowMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        return friendsFollowMapper.deleteById(id) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer saveOrUpdateOrDeleteBatchFriendsFollow(Long tenantId, List<FriendsFollowParam> params){
        if(Collections3.isNotEmpty(params)){
            List<Long> friendsFollowIds = new ArrayList<>();
            List<FriendsFollowDO> needInsertFriendsFollowDOS = new ArrayList<>();
            List<FriendsFollowDO> needUpdateFriendsFollowDOS = new ArrayList<>();
            Map<String, Long> frendsCodeAndIdMap = null;

            List<FriendsFollowDO> oldFriendsFollowDOS = friendsFollowMapper.selectList(new LambdaQueryWrapper<FriendsFollowDO>());
            if(Collections3.isNotEmpty(oldFriendsFollowDOS)) {
                frendsCodeAndIdMap = oldFriendsFollowDOS.parallelStream().collect(Collectors.toMap(FriendsFollowDO::getFriendsCode, FriendsFollowDO::getId, (o, n) -> o));
            }

            for(FriendsFollowParam d:params){
                FriendsFollowDO friendsFollowDO = BeanUtil.convertBean(d, FriendsFollowDO.class);
                Long friendsFollowId = 0L;

                if(frendsCodeAndIdMap!=null && frendsCodeAndIdMap.containsKey(d.getFriendsCode())){
                    friendsFollowId = frendsCodeAndIdMap.get(d.getFriendsCode());
                    friendsFollowDO.setId(friendsFollowId);
                    friendsFollowDO.setModifyTime(LocalDateTime.now());
                    needUpdateFriendsFollowDOS.add(friendsFollowDO);
                    friendsFollowIds.add(friendsFollowId);
                }else{
                    friendsFollowDO.setCreateTime(LocalDateTime.now());
                    friendsFollowDO.setModifyTime(LocalDateTime.now());
                    if(StringUtils.isNotEmpty(d.getBuildTime())){
                        friendsFollowDO.setBuildTime(DateUtil.strToLocalDateTime(d.getBuildTime()));
                    }
                    friendsFollowId = IdGenerator.getId();
                    friendsFollowDO.setId(friendsFollowId);
                    needInsertFriendsFollowDOS.add(friendsFollowDO);
                    friendsFollowIds.add(friendsFollowId);
                }
            }
            if(Collections3.isNotEmpty(needInsertFriendsFollowDOS)){
                friendsFollowMapper.insertBatchSomeColumn(needInsertFriendsFollowDOS);
            }
            if(Collections3.isNotEmpty(needUpdateFriendsFollowDOS)){
                super.updateBatchById(needUpdateFriendsFollowDOS);
            }
       }
        return 1;
    }
}
